package com.xmlt.core.template.instance;

import java.util.List;

import org.w3c.dom.Element;

import com.xmlt.core.template.TemplateException;
import com.xmlt.core.template.TemplateManager;
import com.xmlt.core.template.TemplateParameter;
import com.xmlt.core.template.types.IChoiceValidator;

public class InstanceReference extends Value {

	public InstanceReference(Element el, TemplateManager tm,
			TemplateParameter p, AbstractInstance parent) {
		super(el, tm, p, parent);
		validator = new InstanceReferenceValidator();
	}
	
	protected final String getInstanceReference() {
		return getElement().getTextContent();
	}
	
	public AbstractInstance resolveReference() throws TemplateException {
		return getManager().loadInstance(getInstanceReference());
	}

	@Override
	public AbstractInstance lookup(String path) {
		String instanceRef = getElement().getTextContent();
		if (instanceRef == null)
			return null;

		try {
			String topLevelInstancePath = instanceRef;
			String subPath = null;
			if (instanceRef.indexOf("#") > -1) {
				topLevelInstancePath = instanceRef.substring(0, instanceRef.indexOf("#"));
				subPath = instanceRef.substring(instanceRef.indexOf("#") + 1, instanceRef.length());
			}
			Instance instance = getManager().loadInstance(topLevelInstancePath);
			synchronized (instance) {
				try {
					instance.setParent(getParent());
					instance.setParameter(getParameterReference());
					AbstractInstance target = instance;
					if (subPath != null) {
						target = instance.lookup(subPath);
					}
					return target.lookup(path);
				} finally {
					instance.setParameter(null);
					instance.setParent(null);
				}
			}
		} catch (TemplateException e) {
		}
		return null;
	}

	public class InstanceReferenceValidator implements IChoiceValidator {

		public InstanceReferenceValidator() {
		}

		@Override
		public boolean validate(String value) {
			return true;
		}

		@Override
		public String getDisplayValue(String value) {
			return value;
		}

		@Override
		public Object getContentValue(String value) {
			return value;
		}

		@Override
		public String[] getChoices() {
			List<Instance> instances = getManager().getInstances(getParameterReference().getReference());
			if (instances == null) {
				return new String[0];
			} else {
				String[] choices = new String[instances.size() + 1];
				choices[0] = "";
				for(int i = 0; i < instances.size(); i++) {
					choices[i + 1] = instances.get(i).getReference();
				}
				return choices;
			}
		}

	}

}
